package com.lgmshare.k3.ui.webview;

import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;
import android.webkit.JsPromptResult;
import android.webkit.JsResult;
import android.webkit.WebChromeClient;
import android.webkit.WebResourceError;
import android.webkit.WebResourceRequest;
import android.webkit.WebResourceResponse;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;

import androidx.appcompat.widget.Toolbar;

import android.widget.TextView;

import com.lgmshare.component.logger.Logger;
import com.lgmshare.k3.R;
import com.lgmshare.k3.ui.base.BaseActivity;

import java.io.File;

/**
 * TODO
 * 一般H5页面加载
 *
 * @author: lim
 * @version: V1.0
 * @description:
 * @datetime: 2015/11/11 16:54
 * @email: lgmshare@gmail.com
 */
public class WebViewActivity extends BaseActivity {

    public static final String EXTRA_WEB_TITLE = "web_title";
    public static final String EXTRA_WEB_URL = "web_url";

    protected ProgressBar mProgressBar;
    protected WebView mWebView;

    protected String mPageTitle;
    protected String mPageUrl;

    private TextView toolbar_title;

    @Override
    protected int onBindLayoutResId() {
        return R.layout.activity_webview;
    }

    @Override
    protected void initData() {
        mPageTitle = getIntent().getStringExtra(EXTRA_WEB_TITLE);
        mPageUrl = getIntent().getStringExtra(EXTRA_WEB_URL);
    }

    @Override
    protected void initView() {
        Toolbar toolbar = findViewById(R.id.toolbar);
        toolbar = findViewById(R.id.toolbar);
        toolbar.setTitle("");
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        toolbar_title = findViewById(R.id.toolbar_title);
        toolbar_title.setText(mPageTitle);
        mProgressBar = findViewById(R.id.progressBar);
        mProgressBar.setMax(100);
        initWebView();
        initWebSetting();
        initWebViewClient();
        initWebChromeClient();
    }

    private void initWebView() {
        mWebView = findViewById(R.id.webView);
        //支持获取手势焦点
        mWebView.requestFocusFromTouch();
    }

    private void initWebSetting() {
        WebSettings settings = mWebView.getSettings();
        // UserInfo settings
        //settings.setUserAgentString("Android");//慎用！在加载一些界面的时候会无法加载
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setDisplayZoomControls(false);
        settings.setDefaultFontSize(16);//默认字体大小
        //支持JS
        settings.setJavaScriptEnabled(true);
        //支持插件
        //settings.setPluginState(WebSettings.PluginState.ON);
        //设置适应屏幕
        settings.setUseWideViewPort(true);
        settings.setLoadWithOverviewMode(true);
        //支持缩放
        settings.setSupportZoom(false);
        //隐藏原生的缩放控件
        settings.setDisplayZoomControls(false);
        //支持内容重新布局
        //1、LayoutAlgorithm.NARROW_COLUMNS ：适应内容大小
        //2、LayoutAlgorithm.SINGLE_COLUMN:适应屏幕，内容将自动缩放
        settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
        settings.supportMultipleWindows();
        settings.setSupportMultipleWindows(true);
        //设置缓存模式
        settings.setDomStorageEnabled(true);
        settings.setDatabaseEnabled(true);
        settings.setCacheMode(WebSettings.LOAD_DEFAULT);
        settings.setAppCacheEnabled(true);
        settings.setAppCachePath(mWebView.getContext().getCacheDir().getAbsolutePath());

        //设置可访问文件
        settings.setAllowFileAccess(true);
        //当webview调用requestFocus时为webview设置节点
        settings.setNeedInitialFocus(true);
        //支持自动加载图片
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            settings.setLoadsImagesAutomatically(true);
        } else {
            settings.setLoadsImagesAutomatically(false);
        }
        //设置编码格式
        settings.setDefaultTextEncodingName("UTF-8");
    }

    private void initWebViewClient() {
        mWebView.setWebViewClient(new WebViewClient() {

            //页面开始加载时
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
                mProgressBar.setVisibility(View.VISIBLE);
            }

            //页面完成加载时
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                mProgressBar.setVisibility(View.GONE);
            }

            //是否在WebView内加载新页面
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
                view.loadUrl(request.toString());
                return true;
            }

            //网络错误时回调的方法
            @Override
            public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
                super.onReceivedError(view, request, error);
                //在这里写网络错误时的逻辑,比如显示一个错误页面 这里我偷个懒不写了
                mProgressBar.setVisibility(View.GONE);
            }

            @TargetApi(Build.VERSION_CODES.M)
            @Override
            public void onReceivedHttpError(WebView view, WebResourceRequest request, WebResourceResponse errorResponse) {
                super.onReceivedHttpError(view, request, errorResponse);
            }

        });
    }

    private void initWebChromeClient() {
        mWebView.setWebChromeClient(new WebChromeClient() {

            @Override
            public void onProgressChanged(WebView view, int progress) {
                // Activities and WebViews measure progress with different scales.
                // The progress meter will automatically disappear when we reach 100%
                Logger.v(TAG, "progress：" + progress);
                if (progress > 80) {
                    mProgressBar.setVisibility(View.GONE);
                }
            }

            @Override
            public void onReceivedTitle(WebView view, String title) {
                super.onReceivedTitle(view, title);
                if (TextUtils.isEmpty(title)) {
                } else if (title.length() > 8) {
                } else if (title.startsWith("http://") || title.startsWith("https://")) {
                } else if (title.endsWith(".jpg")) {
                } else if (title.startsWith(".png")) {
                } else if (title.startsWith(".jpeg")) {
                } else {
                    toolbar_title.setText(title);
                }
            }

            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                Logger.v(TAG, "onJsAlert " + message);
                result.confirm();
                return true;
            }

            @Override
            public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {
                Logger.v(TAG, "onJsConfirm " + message);
                return super.onJsConfirm(view, url, message, result);
            }

            @Override
            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {
                Logger.v(TAG, "onJsPrompt " + url);
                return super.onJsPrompt(view, url, message, defaultValue, result);
            }
        });
    }

    @Override
    protected void initLoad() {
        if (TextUtils.isEmpty(mPageUrl)) {
            showToast("网页地址为空!");
        } else {
            mWebView.loadUrl(mPageUrl);
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        mWebView.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mWebView.onPause();
    }

    /**
     * 当我们加载Html时候，会在我们data/应用package下生成database与cache两个文件夹:
     * 我们请求的Url记录是保存在webviewCache.db里，而url的内容是保存在webviewCache文件夹下.
     * WebView中存在着两种缓存：网页数据缓存（存储打开过的页面及资源）、H5缓存（即AppCache）。
     * <p/>
     * 一、网页缓存
     * <p/>
     * 1、缓存构成
     * /data/data/package_name/cache/
     * /data/data/package_name/database/webview.db
     * /data/data/package_name/database/webviewCache.db
     * <p/>
     * 综合可以得知 webview 会将我们浏览过的网页url已经网页文件(css、图片、js等)保存到数据库表中
     * 缓存模式(5种)
     * LOAD_CACHE_ONLY:  不使用网络，只读取本地缓存数据
     * LOAD_DEFAULT:  根据cache-control决定是否从网络上取数据。
     * LOAD_CACHE_NORMAL: API level 17中已经废弃, 从API level 11开始作用同LOAD_DEFAULT模式
     * LOAD_NO_CACHE: 不使用缓存，只从网络获取数据.
     * LOAD_CACHE_ELSE_NETWORK，只要本地有，无论是否过期，或者no-cache，都使用缓存中的数据。
     * 如：www.taobao.com的cache-control为no-cache，在模式LOAD_DEFAULT下，无论如何都会从网络上取数据，如果没有网络，就会出现错误页面；
     * 在LOAD_CACHE_ELSE_NETWORK模式下，无论是否有网络，只要本地有缓存，都使用缓存。本地没有缓存时才从网络上获取。
     * www.360.com.cn的cache-control为max-age=60，在两种模式下都使用本地缓存数据。
     * <p/>
     * 总结：根据以上两种模式，建议缓存策略为，判断是否有网络，有的话，使用LOAD_DEFAULT，无网络时，使用LOAD_CACHE_ELSE_NETWORK。
     */
    protected void openWebViewCache() {
        mWebView.getSettings().setRenderPriority(WebSettings.RenderPriority.NORMAL);
        mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);  //设置 缓存模式
        //开启 DOM storage API 功能
        mWebView.getSettings().setDomStorageEnabled(true);
        //开启 database storage API 功能
        mWebView.getSettings().setDatabaseEnabled(true);
        String cacheDirPath = getFilesDir().getAbsolutePath() + getCacheDir().getPath();
        Logger.d(TAG, "cacheDirPath=" + cacheDirPath);
        //设置 Application Caches 缓存目录
        mWebView.getSettings().setAppCachePath(cacheDirPath);
        //开启 Application Caches 功能
        mWebView.getSettings().setAppCacheEnabled(true);
    }

    /**
     * 清除WebView缓存
     */
    protected void clearWebViewCache() {
        //清理WebView缓存数据库
        try {
            deleteDatabase("webview.db");
            deleteDatabase("webviewCache.db");
        } catch (Exception e) {
            e.printStackTrace();
        }
        //WebView 缓存文件
        File appCacheDir = new File(getFilesDir().getAbsolutePath() + getCacheDir().getPath());
        Logger.d(TAG, "appCacheDir path=" + appCacheDir.getAbsolutePath());

        File webViewCacheDir = new File(getCacheDir().getAbsolutePath() + "/webviewCache");
        Logger.d(TAG, "webViewCacheDir path=" + webViewCacheDir.getAbsolutePath());
        //删除app 缓存目录
        if (appCacheDir.exists()) {
            deleteFile(appCacheDir);
        }
        //删除webview 缓存目录
        if (webViewCacheDir.exists()) {
            deleteFile(webViewCacheDir);
        }
    }

    /**
     * 递归删除 文件/文件夹
     *
     * @param file
     */
    private void deleteFile(File file) {
        Logger.i(TAG, "delete file path=" + file.getAbsolutePath());
        if (file.exists()) {
            if (file.isFile()) {
                file.delete();
            } else if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (int i = 0; i < files.length; i++) {
                    deleteFile(files[i]);
                }
            }
            file.delete();
        } else {
            Logger.e(TAG, "delete file no exists " + file.getAbsolutePath());
        }
    }

    @Override
    public void onBackPressed() {
        if (mWebView != null && mWebView.canGoBack()) {
            mWebView.goBack();
            return;
        }
        super.onBackPressed();
    }

    @Override
    protected void onStop() {
        if (mWebView != null) {
            mWebView.stopLoading();
        }
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        if (mWebView != null) {
            mWebView.getSettings().setJavaScriptEnabled(false);
            mWebView.loadUrl("about:blank");
            mWebView.clearHistory();
            mWebView.removeAllViews();
            /*setBuiltInZoomControls(true) 引发的crash 这个方法调用以后 如果你触摸屏幕 弹出那个提示框还没消失的时候
            你如果activity结束了 就会报错了。3.0以上 4.4以下很多手机会出现这种情况.
            所以为了规避他，我们通常是在activity的onDestroy方法里手动的将webiew设置成 setVisibility(View.GONE)*/
            mWebView.setVisibility(View.GONE);
            mWebView.setWebChromeClient(null);
            mWebView.setWebViewClient(null);
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }
}
